import java.util.*;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode() {}
    TreeNode(int val) { this.val = val; }
    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}
public class project {
    List<List<Integer>> list=new ArrayList<>();
    Deque<Integer> deque=new ArrayDeque<>();
    public List<List<Integer>> allPathsSourceTarget(int[][] graph) {
        deque.offerLast(0);
        dfs(graph,0,graph.length-1);
        return list;
    }
    public void dfs(int[][] graph,int x,int n){
        if(x==n){
            list.add(new ArrayList<>(deque));
            return ;
        }
        for(int i : graph[x]){
            deque.offerLast(i);
            dfs(graph,i,n);
            deque.pollLast();
        }
    }








    public final TreeNode getTargetCopy(final TreeNode original, final TreeNode cloned, final TreeNode target) {
        return ergodic(cloned,target);
    }
    public TreeNode ergodic(TreeNode cloned,TreeNode target){
        if(cloned==null){
            return null;
        }
        if(cloned.val==target.val){
            return cloned;
        }
        TreeNode left=ergodic(cloned.left,target);
        TreeNode right=ergodic(cloned.right,target);
        return left==null?right:left;
    }









    public int minMovesToSeat(int[] seats, int[] students) {
        Arrays.sort(seats);
        Arrays.sort(students);
        int sum=0;
        for(int i=0;i<seats.length;i++){
            sum+=Math.abs(seats[i]-students[i]);
        }
        return sum;
    }





    Set<Integer> set=new HashSet<>();
    public int numColor(TreeNode root) {
        recursion(root);
        return set.size();
    }
    public void recursion(TreeNode root){
        if(root==null){
            return ;
        }
        set.add(root.val);
        recursion(root.left);
        recursion(root.right);
    }







    int depth=0;
    int count=0;
    public int deepestLeavesSum(TreeNode root) {
        depth=maxdepth(root);
        dfsss(root);
        return count;
    }
    public int maxdepth(TreeNode root){
        if(root==null){
            return 0;
        }
        return Math.max(maxdepth(root.left),maxdepth(root.right))+1;
    }
    public void dfsss(TreeNode root){
        if(root==null){
            return;
        }
        depth--;
        dfsss(root.left);
        if(depth==0){
            count+=root.val;
        }
        dfsss(root.right);
        depth++;
    }







    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return dfss(nums,0,nums.length);
    }
    public TreeNode dfss(int[] nums,int left,int right){
        if(left==right){
            return null;
        }
        int maxIndex=max(nums,left,right);
        TreeNode root=new TreeNode(nums[maxIndex]);
        root.left=dfss(nums,left,maxIndex);
        root.right=dfss(nums,maxIndex+1,right);
        return root;
    }
    public int max(int[] nums,int left,int right){
        int max=left;
        for(int i=left;i<right;i++){
            if(nums[i]>nums[max]){
                max=i;
            }
        }
        return max;
    }











    int sum=0;
    public TreeNode convertBST(TreeNode root) {
        if(root==null){
            return null;
        }
        convertBST(root.right);
        sum+=root.val;
        root.val=sum;
        convertBST(root.left);
        return root;
    }









    public int countKDifference(int[] nums, int k) {
        int count=0;
        for(int i=0;i<nums.length-1;i++){
            for(int j=i+1;j<nums.length;j++){
                if(Math.abs(nums[i]-nums[j])==k){
                    count++;
                }
            }
        }
        return count;
    }











    class BSTIterator {
        public int index=0;
        List<Integer> list;
        public BSTIterator(TreeNode root) {
            index=0;
            list=new ArrayList<>();
            inorder(root,list);
        }

        public int next() {
            return list.get(index++);
        }

        public boolean hasNext() {
            return index<list.size();
        }
        public void inorder(TreeNode root,List<Integer> list){
            if(root==null){
                return ;
            }
            inorder(root.left,list);
            list.add(root.val);
            inorder(root.right,list);
        }
    }










    public int finalValueAfterOperations(String[] operations) {
        int count=0;
        for(String s :operations){
            for(int i=0;i<s.length();i++){
                char ch=s.charAt(i);
                if(ch=='-'){
                    count--;
                    break;
                }else if(ch=='+'){
                    count++;
                    break;
                }
            }
        }
        return count;
    }










    public static void main1(String[] args){
        Scanner scan=new Scanner(System.in);
        while(scan.hasNext()){
            int n=scan.nextInt();
            int f1=0;
            int f2=1;
            int f3=0;
            while(f2<n){
                f3=f2+f1;
                f1=f2;
                f2=f3;
            }
            if(Math.abs(f2-n)>Math.abs(f1-n)){
                System.out.println(Math.abs(f1-n));
            }else{
                System.out.println(Math.abs(f2-n));
            }
        }
    }







    public static void main(String[] args){
        Scanner s=new Scanner(System.in);
        Set<String> set=new HashSet<>();
        while(s.hasNext()){
            String str=s.nextLine();
            String[] arr=str.split(" ");
            for(int i=0;i<arr.length;i++){
                set.add(arr[i]);
            }
        }
        System.out.println(set.size());
    }
}
